package com.jrx.anytxn.transaction.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jrx.anytxn.common.constant.Constants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.InternetUtils;
import com.jrx.anytxn.common.uitl.JsonUtils;
import com.jrx.anytxn.common.uitl.SeqUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.constant.BankCardConstant;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.entity.CmCustomerBankcardInfo;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.customer.entity.CmCustomerLimitInfo;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.entity.TlRightsExchangeLog;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerBankcardInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerFirstLevelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerLimitInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerSecondLevelMapper;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.feign.api.response.PrChannelConfigRes;
import com.jrx.anytxn.feign.api.service.IUserApiService;
import com.jrx.anytxn.feign.common.GateWayPredicate;
import com.jrx.anytxn.feign.gateway.bean.ApiResponse;
import com.jrx.anytxn.feign.gateway.bean.DataInfo;
import com.jrx.anytxn.feign.gateway.request.CoreRequest21;
import com.jrx.anytxn.feign.gateway.response.CoreResponse21;
import com.jrx.anytxn.feign.gateway.service.IInnerGatewayService;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.PrProductTable;
import com.jrx.anytxn.param.entity.PrSmsSendingRules;
import com.jrx.anytxn.param.enums.BizTypeEnum;
import com.jrx.anytxn.param.mapper.ext.ExtPrAutoPaymentTableMapper;
import com.jrx.anytxn.param.mapper.ext.ExtPrOrganizationTableMapper;
import com.jrx.anytxn.param.mapper.ext.ExtPrProductTableMapper;
import com.jrx.anytxn.param.service.limit.ICreditLimitMappingService;
import com.jrx.anytxn.param.service.limit.ICreditLimitTypeService;
import com.jrx.anytxn.param.service.partner.IPmMerchantTableService;
import com.jrx.anytxn.param.service.rights.IPrRightsAndInterestsService;
import com.jrx.anytxn.param.service.sms.ISmsSendingRulesService;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.utils.BizTypeProducts;
import com.jrx.anytxn.ribbon.config.GrayVersionConfig;
import com.jrx.anytxn.transaction.bean.DebtBean;
import com.jrx.anytxn.transaction.bean.TemplateWrapper;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.dto.common.CommonAddReq;
import com.jrx.anytxn.transaction.dto.common.SendSmsReq;
import com.jrx.anytxn.transaction.dto.loan.LoanBillQueryRes;
import com.jrx.anytxn.transaction.entity.AmDelinquencyInfo;
import com.jrx.anytxn.transaction.entity.AmLoanAccountInfo;
import com.jrx.anytxn.transaction.entity.AmLoanMainInfo;
import com.jrx.anytxn.transaction.entity.AmRepaymentPlanInfo;
import com.jrx.anytxn.transaction.entity.TlDisbursementLog;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.entity.TlPaymentMapping;
import com.jrx.anytxn.transaction.entity.TlRefundLog;
import com.jrx.anytxn.transaction.entity.TlSmsLog;
import com.jrx.anytxn.transaction.handler.ILoanHandler;
import com.jrx.anytxn.transaction.mapper.base.TlSmsLogMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmDelinquencyInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanAccountInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanMainInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmRepaymentPlanInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentLogMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentMappingMapper;
import com.jrx.anytxn.transaction.service.IDebtCalculationService;
import com.jrx.anytxn.transaction.service.ISmsService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static org.springframework.util.Assert.notNull;

@Service
public class SmsServiceImpl implements ISmsService {

    private static final Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);

    @Autowired
    private ISmsSendingRulesService smsSendingRulesService;
    @Autowired
    private ISegmentService segmentService;
    @Autowired
    private ICustomerService customerService;
    @Resource
    private ExtPrOrganizationTableMapper extPrOrganizationTableMapper;
    @Resource
    private ExtAmRepaymentPlanInfoMapper extAmRepaymentPlanInfoMapper;
    @Resource
    private ExtAmLoanMainInfoMapper extAmLoanMainInfoMapper;
    @Resource
    private ExtCmCustomerBankcardInfoMapper extCmCustomerBankcardInfoMapper;
    @Resource
    private ExtTlPaymentLogMapper extTlPaymentLogMapper;
    @Resource
    private ExtAmLoanAccountInfoMapper extAmLoanAccountInfoMapper;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private GrayVersionConfig grayVersionConfig;
    @Resource
    private ExtCmCustomerSecondLevelMapper extCmCustomerSecondLevelMapper;
    @Autowired
    private ILoanHandler loanHandler;
    @Autowired
    private IPmMerchantTableService pmMerchantTableService;
    @Autowired
    private ICreditLimitMappingService creditLimitMappingService;
    @Autowired
    private ICreditLimitTypeService creditLimitTypeService;
    @Resource
    private ExtCmCustomerLimitInfoMapper extCmCustomerLimitInfoMapper;
    @Resource
    private ExtTlPaymentMappingMapper extTlPaymentMappingMapper;
    @Autowired
    private IDebtCalculationService debtCalculationService;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Lazy
    @Autowired
    private IInnerGatewayService innerGatewayService;
    @Resource
    private TlSmsLogMapper tlSmsLogMapper;
    @Resource
    private ExtPrProductTableMapper extPrProductTableMapper;
    @Resource
    private IUserApiService iUserApiService;

    @Resource
    private ExtPrAutoPaymentTableMapper extPrAutoPaymentTableMapper;
    @Resource
    private ExtCmCustomerFirstLevelMapper extCmCustomerFirstLevelMapper;
    @Resource
    private ExtAmDelinquencyInfoMapper extAmDelinquencyInfoMapper;
    @Autowired
    private IPrRightsAndInterestsService prRightsAndInterestsService;

    /**
     * 放款短信处理 获取短信规则 发送MQ消息
     *
     * @param log
     */
    @Override
    public void disbursementProcess(TlDisbursementLog log) throws Exception {
        logger.info("放款短信处理，订单号：{}，流水号：{}", log.getLoanId(), log.getRefNo());
        //1 根据流水相关信息查询短信规则
        PrSmsSendingRules rulesTable = smsSendingRulesService.getByProductIdAndSmsTypeAndSumStatus(log.getProductId(), TransBizConstant.SMS_TYPE_LOAN, log.getSumStatus(), log.getTenantId());
        if (null == rulesTable) {
            logger.info("订单号：{},未获取到短信发送规则，无需处理", log.getLoanId());
            return;
        }
        //2 生成短信流水
        logger.info("生成放款短信流水");
        TlSmsLog smsLog = generateSmsLogByRemit(rulesTable, log);
        //3 保存短信流水

//        tlSmsLogMapper.insertSelective(smsLog);

        //4 发送MQ消息
        logger.info("开始发送MQ消息，放款短信流水号：{}", smsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(smsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info("放款短信处理完成,流水号:{},结果：{}", smsLog.getSeqNo(), sendResult.toString());
    }

    /**
     * 溢缴款短信处理 获取短信规则 发送MQ消息
     *
     * @param log
     */
    @Override
    public void refundSmsProcess(TlRefundLog log) throws Exception {
        logger.info("溢缴款短信处理，流水号：{}", log.getRefNo());
        //1 根据流水相关信息查询短信规则
        PrSmsSendingRules rulesTable = smsSendingRulesService.getByProductIdAndSmsTypeAndSumStatus(log.getProductId(), TransBizConstant.SMS_TYPE_REFUND_OVERFLOW, log.getSumStatus(), log.getTenantId());
        if (null == rulesTable) {
            logger.info("流水号：{},未获取到短信发送规则，无需处理", log.getRefNo());
            return;
        }
        //2 生成短信流水
        logger.info("生成溢缴款短信流水");
        TlSmsLog smsLog = generateSmsLogByRefund(rulesTable, log);

        //3 发送MQ消息
        logger.info("开始发送MQ消息，溢缴款短信流水号：{}", smsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(smsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info("溢缴款短信处理完成,流水号:{},结果：{}", smsLog.getSeqNo(), sendResult.toString());
    }

    /**
     * 还款短信处理 获取短信规则 发送MQ消息
     *
     * @param log
     */
    @Override
    public void paymentProcess(TlPaymentLog log) throws Exception {
        logger.info("还款短信处理，还款流水号：{}", log.getRefNo());
        //1 根据流水相关信息查询短信规则
        PrSmsSendingRules rulesTable = smsSendingRulesService.getByProductIdAndSmsTypeAndSumStatus(log.getProductId(), log.getPaymentType(), log.getSumStatus(), log.getTenantId());
        if (null == rulesTable) {
            logger.info("订单号：{},未获取到短信发送规则，还款流水还", log.getSeqNo());
            return;
        }
        //2 生成短信流水
        logger.info("生成还款短信流水");
        TlSmsLog smsLog = generateSmsLogByPymt(rulesTable, log);
        //3 保存短信流水
//        tlSmsLogMapper.insertSelective(smsLog);
        //4 发送MQ消息
        logger.info("开始发送MQ消息，还款短信流水号：{}", smsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(smsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info("还款短信处理完成,流水号:{},结果：{}", smsLog.getSeqNo(), sendResult.toString());
    }

    /**
     * 还款提醒短信处理 查询还款计划 发送MQ消息
     *
     * @param rulesList
     */
    @Override
    public void payReminderProcess(List<PrSmsSendingRules> rulesList, Integer maxPoolNumber) {
        //获取业务日期
        PrOrganizationTable org =
                extPrOrganizationTableMapper.selectByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        for (PrSmsSendingRules rules : rulesList) {
            if (TransBizConstant.SMS_TYPE_PAYREMINDER.equals(rules.getSmsType())) {
                //还款提醒短信
                sendPayReminder(org, rules, maxPoolNumber);
            }
            if (TransBizConstant.SMS_TYPE_PAYMENT_REMINDER.equals(rules.getSmsType())) {
                //出账提醒短信
                sendPaymentReminder(org, rules, maxPoolNumber);
            }
            if (TransBizConstant.SMS_TYPE_BILL_PAY_REMINDER.equals(rules.getSmsType())) {
                //账单还款提醒
                sendBillPayReminder(org, rules, maxPoolNumber);
            }
            if (TransBizConstant.SMS_TYPE_OVERDUE_REMINDER.equals(rules.getSmsType())) {
                // 当天业务日期
                Date nextProcessingDate = org.getNextProcessingDate();
                // 当天号数
                String today = DateUtils.format(nextProcessingDate, "dd");
                // 当月最后一天号数
                String endOfMonth = DateUtils.format(DateUtils.getMonthEndTime(nextProcessingDate), "dd");

                //逾期1-2月及以上的模板号
                List<String> lateMoreOneMonthTemplateId = Arrays.asList(
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_20,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_21,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_20,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_21,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_20,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_21
                );
                //逾期3天的模板号
                List<String> lateLessThreeDaysTemplateId = Arrays.asList(
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_18,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_18,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_18
                );
                //逾期5天的模板号
                List<String> lateFiveDaysTemplateId = Arrays.asList(
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_19,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_19,
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_19
                );
                String productId = rules.getProductId();
                boolean xajSeries = BizTypeProducts.getXAJSeriesProducts().contains(productId);
                //逾期1-2月及以上的模板号
                boolean validDay1 = "01".equals(today) && (lateMoreOneMonthTemplateId.contains(rules.getTemplateId()) || xajSeries);
                // 其他天数
                boolean validDayOther = Arrays.asList("11", "12", "13", "14", endOfMonth).contains(today) && (lateLessThreeDaysTemplateId.contains(rules.getTemplateId()) || xajSeries);
                //逾期5天的模板号
                boolean validDay15 = "15".equals(today) && (lateFiveDaysTemplateId.contains(rules.getTemplateId()) || xajSeries);

                if (validDay1 || validDayOther || validDay15) {
                    //账单逾期还款提醒
                    sendOverdueReminder(org, rules, maxPoolNumber);
                }
            }
        }
    }

    /**
     * 根据短信流水生成短信要素类
     *
     * @param tlSmsLog
     * @return
     */
    @Override
    public TemplateWrapper generateTemplateWrapper(TlSmsLog tlSmsLog) throws TxnBizException {
        String smsType = tlSmsLog.getSmsType();
        TemplateWrapper templateWrapper = new TemplateWrapper();
        switch (smsType) {
            case TransBizConstant.SMS_TYPE_LOAN:
                //放款类短信
                //获取订单信息
                AmLoanMainInfo amLoanMainInfo = extAmLoanMainInfoMapper.selectByLoanIdAndCusId(tlSmsLog.getLoanId(), tlSmsLog.getCustomerId(), tlSmsLog.getTenantId());
                if (null != amLoanMainInfo) {
                    templateWrapper.setAmount(amLoanMainInfo.getLoanAmount().toPlainString());
                }
                String launchTime = this.generateTxnTime(amLoanMainInfo);
                templateWrapper.setLaunchTime(launchTime);

                setCardInfo(tlSmsLog, templateWrapper);
                AmRepaymentPlanInfo plan = extAmRepaymentPlanInfoMapper.selectByLoanIdAndBillingTenor(tlSmsLog.getLoanId(), tlSmsLog.getCustomerId(), tlSmsLog.getTenantId(), 1,
                        Collections.singletonList("1"));
                if (Objects.nonNull(plan)) {
                    templateWrapper.setFirstPaymentAmt(plan.getTotalAmount()+"");
                    templateWrapper.setFirstPaymentDate(DateUtils.format(plan.getPaymentDueDate()));
                }
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_REFUND_OVERFLOW:
                setCardInfo(tlSmsLog, templateWrapper);
                templateWrapper.setBusinessDate(DateUtils.formatDateTime());
                templateWrapper.setAmount(tlSmsLog.getCurrentAmount() + "");
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_LOAN_DISCOUNT:
                //优惠抵扣放款类短信
                //获取订单信息
                AmLoanMainInfo loanMainInfo = extAmLoanMainInfoMapper.selectByLoanIdAndCusId(tlSmsLog.getLoanId(), tlSmsLog.getCustomerId(), tlSmsLog.getTenantId());
                if (null != loanMainInfo) {
                    templateWrapper.setAmount(loanMainInfo.getLoanAmount().toPlainString());
                }
                String launchTimeTmp = DateUtils.format(loanMainInfo.getTxnTime(), "dd日HH:mm");
                /*if (!DateUtils.sameDate(DateUtils.parseDate(loanMainInfo.getTxnTime()).getTime(), DateUtils.parseDate(loanMainInfo.getCreateTime()).getTime())) {
                    // 23.30 切日后，前端显示实际发生的时间
                    launchTimeTmp = DateUtils.format(DateUtils.addDay(loanMainInfo.getTxnTime(), -1), "dd日HH:mm");
                }*/
                templateWrapper.setLaunchTime(launchTimeTmp);
                templateWrapper.setDiscountAmount(tlSmsLog.getDiscountAmount().toPlainString());
                templateWrapper.setOriginalAmount((loanMainInfo.getLoanAmount().add(tlSmsLog.getDiscountAmount())).toPlainString());
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_PAYREMINDER:
                //提醒类短信
                // 获取还款计划
                List<String> planStatus = new ArrayList<>();
                planStatus.add(TransBizConstant.LOAN_PLAN_STATUS_1);
                List<AmRepaymentPlanInfo> planList = extAmRepaymentPlanInfoMapper.selectByLoanIdAndStatus
                        (tlSmsLog.getLoanId(), planStatus, tlSmsLog.getCustomerId(), tlSmsLog.getTenantId());
                if (CollectionUtils.isNotEmpty(planList)) {
                    templateWrapper.setBillingTenor(planList.get(0).getBillingTenor().toString());
                    templateWrapper.setPaymentDueDate(DateUtils.formatZH(planList.get(0).getPaymentDueDate()));
                    templateWrapper.setAmount(planList.get(0).getTotalAmount().toPlainString());
                }
                // 获取客户当前渠道默认扣款卡
                /*
                CmCustomerBankcardInfo bank = extCmCustomerBankcardInfoMapper.selectBankCardByCondition(
                        tlSmsLog.getCustomerId(), TransBizConstant.Y_FLAG, null, tlSmsLog.getChannel(), tlSmsLog.getTenantId());
                if (null != bank) {
                    String cardNumber = bank.getCardNumber();
                    templateWrapper.setCardNumber(cardNumber);
                    templateWrapper.setLastCardNumber(cardNumber.substring(cardNumber.length() - 4));
                }*/
                return templateWrapper;
            case CustomerConstant.SMS_TYPE_ID_WILL_INVALID:
                String formatDate = tlSmsLog.getSmsContent();
                logger.info("身份证即将过期日期数据：{}", formatDate);
                templateWrapper.setExpireDate(formatDate);
                return templateWrapper;
            case CustomerConstant.SMS_TYPE_ID_INVALID:
                templateWrapper.setMobile(tlSmsLog.getMobile());
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_CANCEL_ORDER:
                //取消订单短信
                String launTime = DateUtils.format(tlSmsLog.getCreateTime(), "dd日HH:mm");
                templateWrapper.setLaunchTime(launTime);//交易时间
                templateWrapper.setAmount(tlSmsLog.getCurrentAmount().toPlainString());
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_PAYMENT_REMINDER:
                //出账提醒短信
                String monrh = DateUtils.format(tlSmsLog.getBusinessDate(), DateUtils.DATE_PATTERN).substring(5, 7);
                templateWrapper.setStatementMonth(monrh);//账单月份
                templateWrapper.setAmount(tlSmsLog.getCurrentAmount().toPlainString());//当期账单金额
                templateWrapper.setPaymentDueDate(DateUtils.formatDate(tlSmsLog.getBusinessDate(), "MM月dd日"));//还款日
                templateWrapper.setCanStagingAmount(tlSmsLog.getCanStagingAmount().toPlainString());//可分期金额
                BigDecimal currBalance = tlSmsLog.getCurrentAmount().subtract(tlSmsLog.getCanStagingAmount());
                templateWrapper.setCurrBalance(currBalance.toPlainString());//余额
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_BILL_PAY_REMINDER:
                //账单还款提醒
                String monrh1 = DateUtils.format(tlSmsLog.getBusinessDate(), DateUtils.DATE_PATTERN).substring(5, 7);
                templateWrapper.setStatementMonth(monrh1);//账单月份
                templateWrapper.setPaymentDueDate(DateUtils.formatDate(tlSmsLog.getBusinessDate(), "MM月dd日"));//还款日
                templateWrapper.setCurrBalance(tlSmsLog.getCurrentAmount().subtract(tlSmsLog.getCanStagingAmount()).toPlainString());//余额
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_OVERDUE_REMINDER:
                //逾期提醒
                Date businessDate = tlSmsLog.getBusinessDate();
                templateWrapper.setBusinessDate(DateUtils.formatZH(businessDate));
                if (TransBizConstant.SMS_OVERDUE_TEMPLATE_20.equals(tlSmsLog.getTemplateId()) ||
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_21.equals(tlSmsLog.getTemplateId()) ||
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_20.equals(tlSmsLog.getTemplateId()) ||
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_21.equals(tlSmsLog.getTemplateId()) ||
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_20.equals(tlSmsLog.getTemplateId()) ||
                        TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_21.equals(tlSmsLog.getTemplateId())
                ){
                    businessDate = DateUtils.getLastMonthLastDay(businessDate);
                }
                String monrh2 = DateUtils.format(businessDate, DateUtils.DATE_PATTERN).substring(5, 7);
                templateWrapper.setStatementMonth(monrh2);//账单生成月份
                templateWrapper.setAmount(tlSmsLog.getCurrentAmount().toPlainString());//本月剩余应还金额
                templateWrapper.setDelqDays(tlSmsLog.getSmsContent());
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_INVITE_NEW:
                // 邀新发券短信
                // 邀新无借据id-此字段作为 “权益名称---卡密”使用
                String loanId = tlSmsLog.getLoanId();
                if (StringUtils.isNotBlank(loanId)) {
                    String[] rightsInfo = loanId.split("---");
                    if (rightsInfo.length >= 2) {
                        templateWrapper.setRightsName(rightsInfo[0]);
                        templateWrapper.setCardPassword(rightsInfo[1]);
                    }
                }
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_GRANT_COUPON_RIGHTS:
            case TransBizConstant.SMS_TYPE_RIGHTS_REMINDER://下发权益或资格成功发送短信
                CmCustomerFirstLevel customerFirstLevelTmp = null;
                try {
                    customerFirstLevelTmp = customerService.getFirstLevelByCondition(tlSmsLog.getCustomerId(),
                            tlSmsLog.getOrganizationId(), tlSmsLog.getTenantId());
                } catch (TxnBizException e) {
                    logger.error("未查询到客户信息", e);
                    return templateWrapper;
                }
                String cstName = customerFirstLevelTmp.getChineseName();
                String cstSex = customerFirstLevelTmp.getSex();
                if ("1".equals(cstSex)) {
                    cstSex = "女士";
                } else {
                    cstSex = "先生";
                }
                templateWrapper.setExpireDate(tlSmsLog.getSmsContent());
                templateWrapper.setCustomerName(cstName);
                templateWrapper.setCustomerSex(cstSex);
                // 抢券无借据id-此字段作为 “权益名称”使用
                templateWrapper.setRightsName(tlSmsLog.getLoanId());
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_EXCHANGE_RIGHTS://兑换卡密商品成功发送短信
                CmCustomerFirstLevel customerFirstLevelTemp = null;
                try {
                    customerFirstLevelTemp = customerService.getFirstLevelByCondition(tlSmsLog.getCustomerId(),
                            tlSmsLog.getOrganizationId(), tlSmsLog.getTenantId());
                } catch (TxnBizException e) {
                    logger.error("未查询到客户信息", e);
                    return templateWrapper;
                }
                String custName = customerFirstLevelTemp.getChineseName();
                String custSex = customerFirstLevelTemp.getSex();
                if ("1".equals(custSex)) {
                    custSex = "女士";
                } else {
                    custSex = "先生";
                }
                templateWrapper.setCustomerName(custName);
                templateWrapper.setCustomerSex(custSex);
                // 兑换权益无loanId-此字段作为 “权益名称---卡密”使用
                String loanIdTemp = tlSmsLog.getLoanId();
                if (StringUtils.isNotBlank(loanIdTemp)) {
                    String[] rightsInfo = loanIdTemp.split("---");
                    if (rightsInfo.length >= 2) {
                        templateWrapper.setRightsName(rightsInfo[0]);
                        templateWrapper.setCardPassword(rightsInfo[1]);
                    }
                }
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_HALF_ACTIVITY_REMIND:
                return templateWrapper;
            case TransBizConstant.SMS_TYPE_BEFORE_RENEWAL:
            case TransBizConstant.SMS_TYPE_BEFORE_NOT_RENEWAL:
            case TransBizConstant.SMS_TYPE_AFTER_RENEWAL:
            case TransBizConstant.SMS_TYPE_AFTER_NOT_RENEWAL:
            case TransBizConstant.SMS_TYPE_AFTER_UNUSED_RENEWAL:
                CmCustomerFirstLevel firstLevel;
                try {
                    firstLevel = customerService.getFirstLevelByCondition(tlSmsLog.getCustomerId(),
                            tlSmsLog.getOrganizationId(), tlSmsLog.getTenantId());
                } catch (TxnBizException e) {
                    logger.error("未查询到客户信息", e);
                    return templateWrapper;
                }
                if ("1".equals(firstLevel.getSex())) {
                    custSex = "女士";
                } else {
                    custSex = "先生";
                }
                templateWrapper.setCustomerName(firstLevel.getChineseName());
                templateWrapper.setCustomerSex(custSex);
                String expiryDate = tlSmsLog.getSmsContent();
                templateWrapper.setExpireDate(expiryDate);
                return templateWrapper;
            default:
                //还款类短信
                //查询还款流水
                TlPaymentLog tlPaymentLog = extTlPaymentLogMapper.selectBySeqNoAndTenantId(tlSmsLog.getSeqNo(), tlSmsLog.getTenantId());
                if (null != tlPaymentLog) {
                    String cardNumber = tlPaymentLog.getPayerAccount();//扣款卡号
                    templateWrapper.setCardNumber(cardNumber);
                    templateWrapper.setLastCardNumber(cardNumber.substring(cardNumber.length() - 4));
                    templateWrapper.setAmount(tlPaymentLog.getAmount().toPlainString());
                    String busiDate = DateUtils.formatDate(tlPaymentLog.getBusinessDate(), "MM月dd日");
                    templateWrapper.setBusinessDate(busiDate);
                    String postTime = DateUtils.format(tlPaymentLog.getUpdateTime(), "dd日HH:mm");
                    templateWrapper.setLaunchTime(postTime);//交易时间
                    templateWrapper.setCurrBalance(tlSmsLog.getCurrentAmount().subtract(tlSmsLog.getCanStagingAmount()).toPlainString());//余额
                    // 设置响应信息
                    templateWrapper.setReturnMsg(tlSmsLog.getSmsContent());
                }
                return templateWrapper;
        }

    }

    public void setCardInfo(TlSmsLog tlSmsLog, TemplateWrapper templateWrapper) {
        List<CmCustomerBankcardInfo> list = extCmCustomerBankcardInfoMapper.selectByDefaultGetFlag(tlSmsLog.getCustomerId(), tlSmsLog.getChannel(), tlSmsLog.getTenantId(), BankCardConstant.DEFAULT_FLAG_Y);
        if (CollectionUtils.isNotEmpty(list)) {
            CmCustomerBankcardInfo bank = list.get(0);
            if (null != bank) {
                String cardNumber = bank.getCardNumber();
                templateWrapper.setCardNumber(cardNumber);
                templateWrapper.setBankName(bank.getBankName());
                templateWrapper.setLastCardNumber(cardNumber.substring(cardNumber.length() - 4));
            }
        }
    }

    /**
     * 发送延迟短信
     */
    @Override
    public void smsSendProcess(TlSmsLog smsLog) throws Exception {
        //4 发送MQ消息
        logger.info("开始发送MQ消息，放款短信流水号：{}", smsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(smsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info("放款短信处理完成,流水号:{},结果：{}", smsLog.getSeqNo(), sendResult.toString());
    }

    @Override
    public void sendWeChat(TlSmsLog tlSmsLog) throws TxnBizException, SocketException {
        if (StringUtils.isBlank(tlSmsLog.getWxTemplateId())) {
            logger.error("未配置微信模板编号");
            return;
        }
        //获取2级客户信息
        CmCustomerSecondLevel secondLevel = customerService.getSecondByChannelAndCustomerIdAndTensnId(tlSmsLog.getChannel(), tlSmsLog.getCustomerId(), tlSmsLog.getTenantId(), null);
        //获取一级客户信息
        CmCustomerFirstLevel firstLevel = customerService.getFirstLevelByCondition(secondLevel.getCustomerId(), secondLevel.getOrganizationId(), secondLevel.getTenantId());
        logger.info("微信通知短信信息：{}", JSON.toJSONString(tlSmsLog));
        logger.info("微信通知二级客户表信息：{}", JSON.toJSONString(secondLevel));
        CoreRequest21 req = new CoreRequest21();
        req.setServiceId(TransBizConstant.GATEWAY_SERVICE_ID);
        req.setServiceIp(InternetUtils.getLocalIp());
        req.setTenantId(tlSmsLog.getTenantId());
        req.setServiceSeq(tlSmsLog.getSeqNo());
        req.setTemplateId(tlSmsLog.getWxTemplateId());
        req.setMobile(secondLevel.getMobile());
        req.setUnionId(secondLevel.getUnionId());
        //微信消息模板跳转地址
        String pagePath = "pages/home/home";

        JSONObject param = new JSONObject();
        param.put("tenantId", tlSmsLog.getTenantId());
        param.put("channelNo", tlSmsLog.getChannel());
        ApiResponse<PrChannelConfigRes> prChannelConfig = iUserApiService.getPrChannelConfig(param.toJSONString());
        notNull(prChannelConfig.getData(), prChannelConfig.getMessage());
        String appId = prChannelConfig.getData().getWeixinAppId();
        req.setAppId(appId);
        List<DataInfo> dataList = new ArrayList<>();

        if (TransBizConstant.SMS_TYPE_REFUND.equals(tlSmsLog.getSmsType())) {
            String familyName = getFamilyName(firstLevel.getChineseName());//获取姓氏
            String sex = "";
            if ("0".equals(firstLevel.getSex())) {
                sex = "先生:";
            } else if ("1".equals(firstLevel.getSex())) {
                sex = "女士:";
            }
            DataInfo firstData = new DataInfo();
            firstData.setKey("first");
            firstData.setValue("尊敬的" + familyName + sex);
            firstData.setColor("#000000");
            dataList.add(firstData);
            TlPaymentLog tlPaymentLog = extTlPaymentLogMapper.selectBySeqNoAndTenantId(tlSmsLog.getSeqNo(), tlSmsLog.getTenantId());
            logger.info("退款信息：{}", JSON.toJSONString(tlPaymentLog));

            if (null != tlPaymentLog) {
                DataInfo productTypeData = new DataInfo();
                String productType;
                if (BizTypeProducts.PRODUCT_XYJY.equals(tlSmsLog.getProductId())) {
                    productType = "您兴安花信用就医";
                } else {
                    //查询客户收款卡
                    CmCustomerBankcardInfo cond = new CmCustomerBankcardInfo();
                    cond.setCustomerId(tlSmsLog.getCustomerId());
                    cond.setTenantId(tlSmsLog.getTenantId());
                    cond.setChannel(tlSmsLog.getChannel());

                    cond.setCardType(TransBizConstant.CARD_TYPE_0);
                    cond.setCardStatus(TransBizConstant.STATUS_1);
                    cond.setDefaultPayFlag("N");
                    List<CmCustomerBankcardInfo> bankcardInfoList = extCmCustomerBankcardInfoMapper.selectByCondition(cond);
                    String cardNumber = bankcardInfoList.get(0).getCardNumber();
                    String lastCardNumber = cardNumber.substring(cardNumber.length() - 4);
                    productType = "您尾号" + lastCardNumber + "的兴安花卡最新交易信息";
                }
                productTypeData.setKey("productType");
                productTypeData.setValue(productType);
                productTypeData.setColor("#000000");
                dataList.add(productTypeData);

                String launTime = DateUtils.format(tlSmsLog.getCreateTime(), "dd日HH:mm");
                DataInfo timeData = new DataInfo();
                timeData.setKey("time");
                timeData.setValue(launTime);
                timeData.setColor("#000000");
                dataList.add(timeData);

                DataInfo typeData = new DataInfo();
                typeData.setKey("type");
                typeData.setValue("退款");
                typeData.setColor("#000000");
                dataList.add(typeData);

                DataInfo numberData = new DataInfo();
                numberData.setKey("number");
                numberData.setValue("人民币 " + tlPaymentLog.getAmount() + " 元");
                numberData.setColor("#0000FF");
                dataList.add(numberData);


                //根据产品ID查询产品对应的节点
                String limitId = creditLimitMappingService.getLimitId(tlPaymentLog.getOrganizationId(), tlPaymentLog.getChannel(), tlPaymentLog.getProductId(), tlPaymentLog.getTenantId());
                String useMode = creditLimitTypeService.getUserModal(limitId, tlPaymentLog.getOrganizationId(), tlPaymentLog.getTenantId());
                CmCustomerLimitInfo cmCustomerLimitInfo = null;
                if ("0".equals(useMode)) {
                    cmCustomerLimitInfo = extCmCustomerLimitInfoMapper.selectByTenIdAndCusIdAndLimitId(tlPaymentLog.getTenantId(), tlPaymentLog.getCustomerId(), limitId);
                } else {
                    cmCustomerLimitInfo = extCmCustomerLimitInfoMapper.selectCustomerLimitInfo(tlPaymentLog.getCustomerId(), tlPaymentLog.getOrganizationId(), limitId, null, tlPaymentLog.getTenantId());
                }

                DataInfo remarkData = new DataInfo();
                remarkData.setKey("remark");
                remarkData.setValue("交易商户：" + tlPaymentLog.getMerchantName() + "\n目前您厦门国际银行兴安花可用额度为" + cmCustomerLimitInfo.getLimitAvailable() + "元。" +
                        "\n周一至周四消费满299元，即可抢周末5折消费券，详情请戳↓");
                remarkData.setColor("#FF0000");
                dataList.add(remarkData);
                req.setPagePath(pagePath);
            }
        } else if (TransBizConstant.SMS_TYPE_LOAN.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_CANCEL_ORDER.equals(tlSmsLog.getSmsType())) {

            String familyName = getFamilyName(firstLevel.getChineseName());//获取姓氏
            String sex = "";
            if ("0".equals(firstLevel.getSex())) {
                sex = "先生:";
            } else if ("1".equals(firstLevel.getSex())) {
                sex = "女士:";
            }
            DataInfo firstData = new DataInfo();
            firstData.setKey("first");
            firstData.setValue("尊敬的" + familyName + sex);
            firstData.setColor("#000000");
            dataList.add(firstData);
            AmLoanMainInfo amLoanMainInfo = extAmLoanMainInfoMapper.selectByLoanIdAndCusId(tlSmsLog.getLoanId(), tlSmsLog.getCustomerId(), tlSmsLog.getTenantId());
            logger.info("支付信息：{}", JSON.toJSONString(amLoanMainInfo));
            if (null != amLoanMainInfo) {
                DataInfo productTypeData = new DataInfo();
                String productType;
                if (BizTypeProducts.PRODUCT_XYJY.equals(amLoanMainInfo.getProductId())) {
                    productType = "您的信用就医-兴安花";
                } else {
                    //查询客户收款卡
                    CmCustomerBankcardInfo cond = new CmCustomerBankcardInfo();
                    cond.setCustomerId(tlSmsLog.getCustomerId());
                    cond.setTenantId(tlSmsLog.getTenantId());
                    cond.setChannel(tlSmsLog.getChannel());

                    cond.setCardType(TransBizConstant.CARD_TYPE_0);
                    cond.setCardStatus(TransBizConstant.STATUS_1);
                    cond.setDefaultPayFlag("N");
                    List<CmCustomerBankcardInfo> bankcardInfoList = extCmCustomerBankcardInfoMapper.selectByCondition(cond);
                    String cardNumber = bankcardInfoList.get(0).getCardNumber();
                    String lastCardNumber = cardNumber.substring(cardNumber.length() - 4);
                    productType = "您尾号" + lastCardNumber + "的兴安花卡最新交易信息";
                }
                productTypeData.setKey("productType");
                productTypeData.setValue(productType);
                productTypeData.setColor("#000000");
                dataList.add(productTypeData);

                String launchTimeTmp = this.generateTxnTime(amLoanMainInfo);
                DataInfo timeData = new DataInfo();
                timeData.setKey("time");
                timeData.setValue(launchTimeTmp);
                timeData.setColor("#000000");
                dataList.add(timeData);

                String type = "";
                if (TransBizConstant.SMS_TYPE_LOAN.equals(tlSmsLog.getSmsType())) {
                    type = "支付";
                } else if (TransBizConstant.SMS_TYPE_CANCEL_ORDER.equals(tlSmsLog.getSmsType())) {
                    type = "支付撤销";
                }
                DataInfo typeData = new DataInfo();
                typeData.setKey("type");
                typeData.setValue(type);
                typeData.setColor("#000000");
                dataList.add(typeData);

                DataInfo numberData = new DataInfo();
                numberData.setKey("number");
                numberData.setValue("人民币 " + amLoanMainInfo.getLoanAmount() + " 元");
                numberData.setColor("#0000FF");
                dataList.add(numberData);

                //根据产品ID查询产品对应的节点
                String limitId = creditLimitMappingService.getLimitId(amLoanMainInfo.getOrganizationId(), amLoanMainInfo.getChannel(), amLoanMainInfo.getProductId(), amLoanMainInfo.getTenantId());
                String useMode = creditLimitTypeService.getUserModal(limitId, amLoanMainInfo.getOrganizationId(), amLoanMainInfo.getTenantId());
                CmCustomerLimitInfo cmCustomerLimitInfo = null;
                if ("0".equals(useMode)) {
                    cmCustomerLimitInfo = extCmCustomerLimitInfoMapper.selectByTenIdAndCusIdAndLimitId(amLoanMainInfo.getTenantId(), amLoanMainInfo.getCustomerId(), limitId);
                } else {
                    cmCustomerLimitInfo = extCmCustomerLimitInfoMapper.selectCustomerLimitInfo(amLoanMainInfo.getCustomerId(), amLoanMainInfo.getOrganizationId(), limitId, amLoanMainInfo.getContractNumber(),
                            amLoanMainInfo.getTenantId());
                }

                DataInfo remarkData = new DataInfo();
                String remark = "";

                if (BizTypeProducts.PRODUCT_XYJY.equals(tlSmsLog.getProductId())) {
                    remark = "目前您厦门国际银行兴安花信用就医可用额度为" + cmCustomerLimitInfo.getLimitAvailable() + "元。";
                } else if (BizTypeProducts.PRODUCT_XAH.contains(tlSmsLog.getProductId())) {
                    remark = "交易商户：" + amLoanMainInfo.getMerchantName() + "\n目前您厦门国际银行兴安花可用额度为" + cmCustomerLimitInfo.getLimitAvailable() + "元。" +
                            "\n周一至周四消费满299元，即可抢周末5折消费券，详情请戳↓";
                }
                remarkData.setKey("remark");
                remarkData.setValue(remark);
                remarkData.setColor("#FF0000");
                dataList.add(remarkData);
                req.setPagePath(pagePath);
            }
        } else if (TransBizConstant.SMS_TYPE_PAYMENT_REMINDER.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_BILL_PAY_REMINDER.equals(tlSmsLog.getSmsType())) {

            String familyName = getFamilyName(firstLevel.getChineseName());//获取姓氏
            String sex = "";
            if ("0".equals(firstLevel.getSex())) {
                sex = "先生:";
            } else if ("1".equals(firstLevel.getSex())) {
                sex = "女士:";
            }
            DataInfo firstData = new DataInfo();
            firstData.setKey("first");
            firstData.setValue("尊敬的" + familyName + sex);
            firstData.setColor("#000000");
            dataList.add(firstData);

            String month = DateUtils.format(tlSmsLog.getBusinessDate(), DateUtils.DATE_PATTERN).substring(5, 7);
            DataInfo headinfoData = new DataInfo();
            headinfoData.setKey("headinfo");
            headinfoData.setValue("您厦门国际银行兴安花" + month + "月账单");
            headinfoData.setColor("#000000");
            dataList.add(headinfoData);

            String payDate = DateUtils.format(tlSmsLog.getBusinessDate(), DateUtils.DATE_PATTERN_ZH);
            DataInfo payDateData = new DataInfo();
            payDateData.setKey("payDate");
            payDateData.setValue(payDate);
            payDateData.setColor("#000000");
            dataList.add(payDateData);

            DataInfo payMoneyData = new DataInfo();
            payMoneyData.setKey("payMoney");
            payMoneyData.setValue("人民币" + tlSmsLog.getCurrentAmount().toPlainString() + "元");
            payMoneyData.setColor("#000000");
            dataList.add(payMoneyData);

            String message = "";
            if (TransBizConstant.SMS_TYPE_BILL_PAY_REMINDER.equals(tlSmsLog.getSmsType())) {
                message = "我行将于最后还款日9:00自动扣款，请确保您扣款账户余额充足，如已还款请略过";
            } else {
                PrProductTable productTable = extPrProductTableMapper.selectByProductIdAndStatus("XIBXAH000003", "1", tlSmsLog.getTenantId());
                if (tlSmsLog.getCanStagingAmount().compareTo(productTable.getMinAmount()) >= 0) {
                    message = "其中" + tlSmsLog.getCanStagingAmount() + "元可办理分期还款，最高可分12期。分期速戳↓";
                } else {
                    message = "我行将于最后还款日9:00自动扣款，请确保您扣款账户余额充足，速戳查询账单详情↓";
                }
                req.setPagePath(pagePath);
            }

            DataInfo remarkData = new DataInfo();
            remarkData.setKey("remark");
            remarkData.setValue(message);
            remarkData.setColor("#FF0000");
            dataList.add(remarkData);

        } else if (TransBizConstant.SMS_TYPE_AUTO_PYMT.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_PREPAY.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_PRETERMINTION.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_OVERDUE.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_PAY.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_PREPAY_CURR.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_BILL_PREPAY_CURR.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_BILL_PREPAY.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_BILL_PAY.equals(tlSmsLog.getSmsType()) ||
                TransBizConstant.SMS_TYPE_BILL_OVERDUE_PAY.equals(tlSmsLog.getSmsType())) {
            TlPaymentLog tlPaymentLog = extTlPaymentLogMapper.selectBySeqNoAndTenantId(tlSmsLog.getSeqNo(), tlSmsLog.getTenantId());
            if (tlPaymentLog != null) {

                String familyName = getFamilyName(firstLevel.getChineseName());//获取姓氏
                String sex = "";
                if ("0".equals(firstLevel.getSex())) {
                    sex = "先生";
                } else if ("1".equals(firstLevel.getSex())) {
                    sex = "女士";
                }

                if (tlPaymentLog.getSumStatus().equals(TransBizConstant.PAYMENT_LOG_SUM_STATUS_S)) {
                    //成功
                    DataInfo firstData = new DataInfo();
                    firstData.setKey("first");
                    firstData.setValue("尊敬的" + familyName + sex + "，收到您成功还款：");
                    firstData.setColor("#000000");
                    dataList.add(firstData);

                    DataInfo transferMoneyData = new DataInfo();
                    transferMoneyData.setKey("transferMoney");
                    transferMoneyData.setValue("人民币" + tlPaymentLog.getAmount() + "元");
                    transferMoneyData.setColor("#000000");
                    dataList.add(transferMoneyData);

                    String timr = DateUtils.format(tlPaymentLog.getUpdateTime(), "dd日HH:mm");
                    DataInfo transferTimeData = new DataInfo();
                    transferTimeData.setKey("transferTime");
                    transferTimeData.setValue(timr);
                    transferTimeData.setColor("#000000");
                    dataList.add(transferTimeData);

                    DataInfo acceptAccountData = new DataInfo();
                    acceptAccountData.setKey("acceptAccount");
                    acceptAccountData.setValue("厦门国际银行兴安花");
                    acceptAccountData.setColor("#000000");
                    dataList.add(acceptAccountData);

                    String cardNumber = tlPaymentLog.getPayerAccount();//扣款卡号
                    DataInfo sendAccountData = new DataInfo();
                    sendAccountData.setKey("sendAccount");
                    sendAccountData.setValue(tlPaymentLog.getPayerBankName() + "(" + cardNumber.substring(cardNumber.length() - 4) + ")");
                    sendAccountData.setColor("#000000");
                    dataList.add(sendAccountData);

                    PrOrganizationTable org = organizationTableService.findByOrId(tlSmsLog.getOrganizationId(),
                            tlSmsLog.getTenantId());
                    Date bussinessDate = org.getNextProcessingDate();

                    List<TlPaymentMapping> mappingList = extTlPaymentMappingMapper.selectByPaymentSeqAndCustomerId(tlSmsLog.getSeqNo(), tlSmsLog.getCustomerId(), tlSmsLog.getTenantId());
                    //计算应收欠款
                    BigDecimal balance = BigDecimal.ZERO;
                    for (TlPaymentMapping mapping : mappingList) {
                        AmLoanAccountInfo loanAccountInfo = extAmLoanAccountInfoMapper.selectByLoanId(mapping.getLoanId(), mapping.getCustomerId(), mapping.getTenantId());
                        //计算欠款
                        DebtBean debtBean = null;
                        if (TransBizConstant.SMS_TYPE_BILL_PREPAY_CURR.equals(tlSmsLog.getSmsType())) {
                            debtBean = debtCalculationService.getBalance(loanAccountInfo, bussinessDate, null, false, true,
                                    null);
                        } else {
                            debtBean = debtCalculationService.getBalance(loanAccountInfo, bussinessDate, null, true, true,
                                    null);
                        }
                        BigDecimal debtAmt = debtBean.getTotalAmount();
                        if (debtAmt.compareTo(BigDecimal.ZERO) > 0) {
                            balance = balance.add(debtAmt);
                        }
                    }

                    String remarkValue = "";
                    if (balance.compareTo(BigDecimal.ZERO) <= 0) {
                        //已经结清
                        remarkValue = "您兴安花本期账单已还清。";
                    } else {
                        remarkValue = "您兴安花本期账单剩余未还金额为人民币" + balance + "元。";
                    }
                    DataInfo remarkData = new DataInfo();
                    remarkData.setKey("remark");
                    remarkData.setValue(remarkValue);
                    remarkData.setColor("#000000");
                    dataList.add(remarkData);
                } else {
                    //失败
                    DataInfo firstData = new DataInfo();
                    firstData.setKey("first");
                    firstData.setValue(familyName + sex + "您好，由于您绑定的银行卡账户，" + tlPaymentLog.getReturnMsg() + "您兴安花还款失败：");
                    firstData.setColor("#000000");
                    dataList.add(firstData);

                    DataInfo keyword1Data = new DataInfo();
                    keyword1Data.setKey("keyword1");
                    keyword1Data.setValue("人民币" + tlPaymentLog.getAmount().toPlainString() + "元");
                    keyword1Data.setColor("#000000");
                    dataList.add(keyword1Data);

                    String cardNumber = tlPaymentLog.getPayerAccount();//扣款卡号
                    DataInfo keyword2Data = new DataInfo();
                    keyword2Data.setKey("keyword2");
                    keyword2Data.setValue(tlPaymentLog.getPayerBankName() + "(" + cardNumber.substring(cardNumber.length() - 4) + ")");
                    keyword2Data.setColor("#000000");
                    dataList.add(keyword2Data);

                    DataInfo remarkData = new DataInfo();
                    remarkData.setKey("remark");
                    remarkData.setValue("请您检查还款卡是否可用于还款，银行将会再次扣款，如已还款已略过。");
                    remarkData.setColor("#000000");
                    dataList.add(remarkData);
                }
            }
        }
        req.setDataList(dataList);

        CoreResponse21 response = null;
        // 调用网关
        try {
            //组装请求参数
            String weChatPushReqJson = JsonUtils.toJSon(req);
            logger.info("微信通知参数：{}", weChatPushReqJson);
            GateWayPredicate<CoreResponse21> weChatPre = () -> innerGatewayService.weChatTemplatePush(weChatPushReqJson);
            response = weChatPre.getRes(weChatPre);
        } catch (Exception e) {
            logger.error("微信调用网关异常", e);
        }

        if (response == null) {
            tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_FAIL);
        } else {
            tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_SUC);
        }

        //如果是微信短信同时发送 需要生成ID 与 seqNo
        if (tlSmsLog.getSendType().equals(TransBizConstant.SEND_TYPE_2)) {
            try {
                tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
            }
            tlSmsLog.setSeqNo(SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM));

        }
        tlSmsLog.setSendType(TransBizConstant.SEND_TYPE_1);//区分短信微信
        //插入短信流水
        tlSmsLogMapper.insertSelective(tlSmsLog);
        logger.info("MQ消费端微信流水处理完成,流水号：{}", tlSmsLog.getSeqNo());

    }

    @Override
    public void sendSmsMq(AmLoanMainInfo amLoanMainInfo, String smsType) throws Exception {
        PrOrganizationTable org = organizationTableService.findByOrId(amLoanMainInfo.getOrganizationId(), amLoanMainInfo.getTenantId());
        Date businessDate = org.getNextProcessingDate();

        //1 判断是否需要发送短信
        PrSmsSendingRules rulesTable = smsSendingRulesService.getByProductIdAndSmsTypeAndSumStatus(amLoanMainInfo.getProductId(), smsType, TransBizConstant.SUM_STATUS_S, amLoanMainInfo.getTenantId());
        if (null == rulesTable) {
            logger.info("订单号：{},未获取到短信发送规则，无需处理", amLoanMainInfo.getLoanId());
            return;
        }
        //2 生成短信流水
        logger.info("生成还款短信流水");
        TlSmsLog tlSmsLog = BeanMapping.copy(amLoanMainInfo, TlSmsLog.class);
        try {
            tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        //查询客户2级信息获取客户手机号
        CmCustomerSecondLevel customer =
                customerService.getSecondByChannelAndCustomerIdAndTensnId(amLoanMainInfo.getChannel(),
                        amLoanMainInfo.getCustomerId(), amLoanMainInfo.getTenantId(), null);
        tlSmsLog.setSeqNo(SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM));
        tlSmsLog.setChannel(amLoanMainInfo.getChannel());
        tlSmsLog.setSmsType(smsType);
        tlSmsLog.setMobile(customer.getMobile());
        tlSmsLog.setTemplateId(rulesTable.getTemplateId());
        tlSmsLog.setSendType(rulesTable.getSendType());
        tlSmsLog.setWxTemplateId(rulesTable.getWxTemplateId());
        if (TransBizConstant.SMS_TYPE_LOAN.equals(smsType)) {
            tlSmsLog.setCreateTime(amLoanMainInfo.getTxnTime());
        } else if (TransBizConstant.SMS_TYPE_CANCEL_ORDER.equals(smsType)) {
            tlSmsLog.setCreateTime(DateUtils.getBusinessTime(new Date(), businessDate));
            tlSmsLog.setSeqNo("CANCEL" + SeqUtils.getSNByLength(26));
        }
        tlSmsLog.setCurrentAmount(amLoanMainInfo.getLoanAmount());
        tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
        tlSmsLog.setBusinessDate(businessDate);

        //3 发送MQ消息
        logger.info("开始发送MQ消息，还款短信流水号：{}", tlSmsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(tlSmsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info("还款短信处理完成,流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());

    }

    @Override
    public void sendSmsMq(TlRightsExchangeLog rightsExchangeLog, String smsType) throws Exception {
        String tenantId = rightsExchangeLog.getTenantId();
        PrOrganizationTable org = organizationTableService.findByOrId(Constants.DEFAULT_ORG_NUMBER, tenantId);
        Date businessDate = org.getNextProcessingDate();

        //1 判断是否需要发送短信
        PrSmsSendingRules rulesTable = smsSendingRulesService.getByProductIdAndSmsTypeAndSumStatus(Constants.DEFAULT_PRODTCT_CODE, smsType, TransBizConstant.SUM_STATUS_S, tenantId);
        if (null == rulesTable) {
            logger.info("短信类型：{},未获取到短信发送规则，无需处理", smsType);
            return;
        }

        //2 生成短信流水
        logger.info("生成邀新发券短信流水");
        TlSmsLog tlSmsLog = BeanMapping.copy(rightsExchangeLog, TlSmsLog.class);
        try {
            tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        tlSmsLog.setOrganizationId(Constants.DEFAULT_ORG_NUMBER);
        tlSmsLog.setProductId(Constants.DEFAULT_PRODTCT_CODE);
        tlSmsLog.setLoanId(rightsExchangeLog.getCouponName() + "---" + rightsExchangeLog.getCardPassword());
        tlSmsLog.setSeqNo(rightsExchangeLog.getId().toString());
        tlSmsLog.setChannel(rightsExchangeLog.getChannel());
        tlSmsLog.setSmsType(smsType);
        tlSmsLog.setMobile(rightsExchangeLog.getChargeAccount());
        tlSmsLog.setTemplateId(rulesTable.getTemplateId());
        tlSmsLog.setSendType(rulesTable.getSendType());
        tlSmsLog.setWxTemplateId(rulesTable.getWxTemplateId());
        tlSmsLog.setCreateTime(rightsExchangeLog.getCreateTime());
        tlSmsLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
        tlSmsLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
        tlSmsLog.setBusinessDate(businessDate);

        //3 发送MQ消息
        logger.info("开始发送MQ消息，邀新成功提醒短信流水号：{}", tlSmsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(tlSmsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info("邀新成功短信处理完成,流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());

    }

    @Override
    public void sendSmsMq(AmLoanMainInfo amLoanMainInfo, BigDecimal totalExemptAmount, String smsType) throws Exception {
        PrOrganizationTable org = organizationTableService.findByOrId(amLoanMainInfo.getOrganizationId(), amLoanMainInfo.getTenantId());
        Date businessDate = org.getNextProcessingDate();

        //1 判断是否需要发送短信
        PrSmsSendingRules rulesTable = smsSendingRulesService.getByProductIdAndSmsTypeAndSumStatus(amLoanMainInfo.getProductId(), smsType, TransBizConstant.SUM_STATUS_S, amLoanMainInfo.getTenantId());
        if (null == rulesTable) {
            logger.info("订单号：{},未获取到短信发送规则，无需处理", amLoanMainInfo.getLoanId());
            return;
        }
        //2 生成短信流水
        logger.info("生成优惠券抵扣支付成功短信流水");
        TlSmsLog tlSmsLog = BeanMapping.copy(amLoanMainInfo, TlSmsLog.class);
        try {
            tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        //查询客户2级信息获取客户手机号
        CmCustomerSecondLevel customer =
                customerService.getSecondByChannelAndCustomerIdAndTensnId(amLoanMainInfo.getChannel(),
                        amLoanMainInfo.getCustomerId(), amLoanMainInfo.getTenantId(), null);
        String currentTimeMillis = System.currentTimeMillis() + "";
        String seqNo = (int) (Math.random() * 100000) + currentTimeMillis;
        tlSmsLog.setSeqNo(seqNo);
        tlSmsLog.setDiscountAmount(totalExemptAmount);
        tlSmsLog.setChannel(amLoanMainInfo.getChannel());
        tlSmsLog.setSmsType(smsType);
        tlSmsLog.setMobile(customer.getMobile());
        tlSmsLog.setTemplateId(rulesTable.getTemplateId());
        tlSmsLog.setSendType(rulesTable.getSendType());
        tlSmsLog.setWxTemplateId(rulesTable.getWxTemplateId());

        if (TransBizConstant.SMS_TYPE_LOAN_DISCOUNT.equals(smsType)) {
            tlSmsLog.setCreateTime(amLoanMainInfo.getTxnTime());
        } else if (TransBizConstant.SMS_TYPE_CANCEL_ORDER.equals(smsType)) {
            tlSmsLog.setCreateTime(DateUtils.getBusinessTime(new Date(), businessDate));
        }
        tlSmsLog.setCurrentAmount(amLoanMainInfo.getLoanAmount());
        tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
        tlSmsLog.setBusinessDate(businessDate);

        //3 发送MQ消息
        logger.info("开始发送MQ消息，生成优惠券抵扣支付成功短信流水：{}", tlSmsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(tlSmsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info("优惠券抵扣支付成功短信处理完成,流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());
    }

    @Override
    public void sendSmsMq(SendSmsReq req) throws Exception {
        PrOrganizationTable org = organizationTableService.findByOrId(Constants.DEFAULT_ORG_NUMBER, req.getTenantId());
        Date businessDate = org.getNextProcessingDate();
        //1 判断是否需要发送短信
        PrSmsSendingRules rulesTable = smsSendingRulesService.getByProductIdAndSmsTypeAndSumStatus(Constants.DEFAULT_PRODTCT_CODE, req.getSmsType(),
                TransBizConstant.SUM_STATUS_S, req.getTenantId());
        if (null == rulesTable) {
            logger.info("短信类型：{},未获取到短信发送规则，无需处理", req.getSmsType());
            return;
        }

        //2 生成短信流水
        logger.info("生成---" + req.getSmsType() + "---短信流水");

        TlSmsLog tlSmsLog = new TlSmsLog();
        try {
            tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        tlSmsLog.setCustomerId(req.getCustomerId());
        tlSmsLog.setTenantId(req.getTenantId());
        tlSmsLog.setOrganizationId(Constants.DEFAULT_ORG_NUMBER);
        tlSmsLog.setProductId(Constants.DEFAULT_PRODTCT_CODE);
        tlSmsLog.setLoanId(req.getLoanId());
        tlSmsLog.setSeqNo(req.getSeqNo());
        tlSmsLog.setChannel(req.getChannel());
        tlSmsLog.setSmsType(req.getSmsType());
        tlSmsLog.setMobile(req.getMobile());
        tlSmsLog.setTemplateId(rulesTable.getTemplateId());
        tlSmsLog.setSendType(rulesTable.getSendType());
        tlSmsLog.setWxTemplateId(rulesTable.getWxTemplateId());
        tlSmsLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
        tlSmsLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
        tlSmsLog.setBusinessDate(businessDate);
        if (!Objects.isNull(req.getCurrentAmount())) {
            tlSmsLog.setCurrentAmount(req.getCurrentAmount());
        }
        if (!Objects.isNull(req.getDiscountAmount())) {
            tlSmsLog.setDiscountAmount(req.getDiscountAmount());
        }
        // 身份有效期校验和额度续期使用
        if (StringUtils.isNotBlank(req.getExpireDate())) {
            tlSmsLog.setSmsContent(req.getExpireDate());
        }

        //3 发送MQ消息
        logger.info("开始发送MQ消息---" + req.getSmsType() + "---提醒短信流水号：{}", tlSmsLog.getSeqNo());
        String jSonMessage = JsonUtils.toJSon(tlSmsLog);
        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
        logger.info(req.getSmsType() + "---流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());
    }


    //生成短信流水
    private TlSmsLog generateSmsLogByRemit(PrSmsSendingRules rulesTable, TlDisbursementLog log) throws TxnBizException {
        TlSmsLog tlSmsLog = BeanMapping.copy(log, TlSmsLog.class);
        try {
            tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        //查询客户2级信息获取客户手机号
        CmCustomerSecondLevel secondCust =
                customerService.getSecondByChannelAndCustomerIdAndTensnId(log.getChannel(),
                        log.getCustomerId(), log.getTenantId(), null);
        tlSmsLog.setMobile(secondCust.getMobile());
        tlSmsLog.setSeqNo(SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM));
        tlSmsLog.setSmsType(TransBizConstant.SMS_TYPE_LOAN);
        tlSmsLog.setTemplateId(rulesTable.getTemplateId());
        tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
        tlSmsLog.setSendType(rulesTable.getSendType());
        return tlSmsLog;
    }

    //生成溢缴款短信流水
    private TlSmsLog generateSmsLogByRefund(PrSmsSendingRules rulesTable, TlRefundLog log) throws TxnBizException {
        TlSmsLog tlSmsLog = BeanMapping.copy(log, TlSmsLog.class);
        try {
            tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        //查询客户2级信息获取客户手机号
        CmCustomerSecondLevel secondCust =
                customerService.getSecondByChannelAndCustomerIdAndTensnId(log.getChannel(),
                        log.getCustomerId(), log.getTenantId(), null);
        tlSmsLog.setMobile(secondCust.getMobile());
        tlSmsLog.setSeqNo(SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM));
        tlSmsLog.setSmsType(TransBizConstant.SMS_TYPE_REFUND_OVERFLOW);
        tlSmsLog.setTemplateId(rulesTable.getTemplateId());
        tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
        tlSmsLog.setSendType(rulesTable.getSendType());
        tlSmsLog.setCurrentAmount(log.getAmount());
        tlSmsLog.setBusinessDate(log.getBusinessDate());
        return tlSmsLog;
    }

    /**
     * 实际还款金额发送短信
     * @param rulesTable
     * @param log
     * @return
     * @throws TxnException
     */
    private TlSmsLog generateSmsLogByPymt(PrSmsSendingRules rulesTable, TlPaymentLog log) throws TxnException {
        //查询客户2级信息获取客户手机号
        CmCustomerSecondLevel customer = customerService.getSecondByChannelAndCustomerIdAndTensnId(log.getChannel(), log.getCustomerId(), log.getTenantId(), null);
        // 本期应还金额
        LoanBillQueryRes loanBillQueryRes = getCurrAmount(rulesTable, customer);
        logger.info("还款金额发送短信查询账单结果：{}", JSONObject.toJSONString(loanBillQueryRes));
        // 兴安借需要 当期余额需要特殊处理
        //当期金额 = 当期账单金额 + 逾期金额
        BigDecimal currentAmount = loanBillQueryRes.getCurrentAmount().add(loanBillQueryRes.getDelqAmount());
        if(BizTypeProducts.getXAJSeriesProducts().contains(log.getProductId())) {
            // 是否包含当期
            boolean containCurrTerm = loanBillQueryRes.getPaymentDd().compareTo(DateUtils.getDayOfMonth(loanBillQueryRes.getToday())) <= 0;
            // 非还款日还款肯定是逾期的只需逾期金额即可
            if (!containCurrTerm) {
                //肯定是逾期的
                currentAmount = loanBillQueryRes.getDelqAmount();
            }
        }
        // 还款成功的需要加上已还金额
        if (TransBizConstant.PAYMENT_LOG_SUM_STATUS_S.equalsIgnoreCase(log.getSumStatus())) {
            currentAmount = currentAmount.add(log.getAmount());
        }

        logger.info("客户ID：{},当期总金额：{}", customer.getCustomerId(), currentAmount);
        TlSmsLog tlSmsLog = BeanMapping.copy(log, TlSmsLog.class);
        try {
            tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        // 本期应还金额
        tlSmsLog.setCurrentAmount(currentAmount);
        if (TransBizConstant.YES_FLAG.equals(loanBillQueryRes.getCanStaging())) {
            tlSmsLog.setCanStagingAmount(loanBillQueryRes.getCanStagingAmount());
        } else {
            tlSmsLog.setCanStagingAmount(BigDecimal.ZERO);
        }
        tlSmsLog.setSmsType(log.getPaymentType());
        tlSmsLog.setMobile(customer.getMobile());
        tlSmsLog.setTemplateId(rulesTable.getTemplateId());
        tlSmsLog.setSendType(rulesTable.getSendType());
        tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
        tlSmsLog.setWxTemplateId(rulesTable.getWxTemplateId());
        tlSmsLog.setChannel(log.getChannel());
        // 失败的场景专用
        tlSmsLog.setSmsContent(log.getReturnMsg());
        return tlSmsLog;
    }

    /**
     * 获取当期应还金额
     * @param rulesTable
     * @param customer
     * @return
     * @throws TxnException
     */
    private LoanBillQueryRes getCurrAmount(PrSmsSendingRules rulesTable, CmCustomerSecondLevel customer) throws TxnException {
        //调用客户当期账单查询
        CommonAddReq req = new CommonAddReq();
        req.setUserId(customer.getUserId());
        req.setChannel(customer.getChannel());
        req.setTenantId(customer.getTenantId());
        //需要根据产品信息出账单
        BizTypeEnum bizType = BizTypeProducts.getBizType(rulesTable.getProductId());
        req.setBizType(bizType.getCode());
        LoanBillQueryRes loanBillQueryRes = loanHandler.loanBillQueryHandle(req);
        return loanBillQueryRes;
    }

    private List<TlSmsLog> generateSmsLogBypayReminder(PrSmsSendingRules prSmsSendingRules, List<AmLoanAccountInfo> accountList, Date busiDate) throws TxnBizException {
        logger.debug("根据还款计划组装短信流水");
        List<TlSmsLog> updateList = new ArrayList<>();
        for (AmLoanAccountInfo accountInfo : accountList) {
            TlSmsLog tlSmsLog = BeanMapping.copy(accountInfo, TlSmsLog.class);
            try {
                tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
            }
            //查询客户2级信息获取客户手机号
            CmCustomerSecondLevel secondCust =
                    customerService.getSecondByChannelAndCustomerIdAndTensnId(accountInfo.getChannel(), accountInfo.getCustomerId(), accountInfo.getTenantId(), null);
            tlSmsLog.setOrganizationId(secondCust.getOrganizationId());
            tlSmsLog.setProductId(prSmsSendingRules.getProductId());
            tlSmsLog.setMobile(secondCust.getMobile());
            tlSmsLog.setTemplateId(prSmsSendingRules.getTemplateId());
            tlSmsLog.setSmsType(TransBizConstant.SMS_TYPE_PAYREMINDER);
            tlSmsLog.setSeqNo(SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM));
            tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
            tlSmsLog.setBusinessDate(busiDate);
            tlSmsLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
            tlSmsLog.setSendType(prSmsSendingRules.getSendType());
            tlSmsLog.setWxTemplateId(prSmsSendingRules.getWxTemplateId());
            tlSmsLog.setChannel(prSmsSendingRules.getChannel());
            tlSmsLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
            updateList.add(tlSmsLog);
        }
        //批量入库
//        extTlSmsLogMapper.insertTlSmsLogList(updateList);

        return updateList;
    }

    //生成逾期提醒短信流水
    private List<TlSmsLog> generateSmsLogByOverdueReminder(PrSmsSendingRules prSmsSendingRules, List<CmCustomerFirstLevel> accountList,
                                                           Date busiDate, List<String> productIds) throws TxnBizException {
        logger.info("组装逾期提醒短信流水");
        List<TlSmsLog> saveList = new ArrayList<>();
        for (CmCustomerFirstLevel customerInfo : accountList) {
            //获取逾期期次
            //统计客户累计逾期几次
            List<AmDelinquencyInfo> amDelinquencyInfos = extAmDelinquencyInfoMapper.groupByCustomerIdList(customerInfo.getCustomerId(), customerInfo.getTenantId())
                    .stream().filter(x -> productIds.contains(x.getProductId())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(amDelinquencyInfos)) {
                continue;
            }
            AmDelinquencyInfo amDelinquencyInfo = amDelinquencyInfos.get(0);
            Integer monthNum = DateUtils.calcGapMonths(amDelinquencyInfo.getDelqDate(), busiDate);

            List<String> lateOneMonthsTemplateId = Arrays.asList(TransBizConstant.SMS_OVERDUE_TEMPLATE_20, TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_20);
            List<String> lateMoreTwoMonthsTemplateId = Arrays.asList(TransBizConstant.SMS_OVERDUE_TEMPLATE_21, TransBizConstant.SMS_OVERDUE_TEMPLATE_XYJY_21);

            if (lateOneMonthsTemplateId.contains(prSmsSendingRules.getTemplateId()) && monthNum != 1){
                continue;
            } else if (lateMoreTwoMonthsTemplateId.contains(prSmsSendingRules.getTemplateId()) && monthNum < 2){
                continue;
            }
            Integer delqDays = amDelinquencyInfo.getDelqDays();
            // 是兴安借产品
            boolean isXaj = BizTypeProducts.getXAJSeriesProducts().contains(amDelinquencyInfo.getProductId());
            if (isXaj) {
                // 兴安借逾期短信提醒短信处理
                boolean sendFlag = overdueReminderLevel(prSmsSendingRules, delqDays);
                if (!sendFlag) {
                    continue;
                }
            }

            //查询客户正常状态贷款账户列表
            List<String> statusList = Arrays.asList(TransBizConstant.LOAN_STATUS_2);
            List<AmLoanAccountInfo> accountInfos =
                    extAmLoanAccountInfoMapper.selectByCustAndChannelAndStatusAndProductId(customerInfo.getCustomerId(),
                            prSmsSendingRules.getChannel(), customerInfo.getTenantId(), statusList, productIds);
            //订单列表为空
            if (CollectionUtils.isEmpty(accountInfos)) {
                continue;
            }

            //筛选符合条件的订单 排除掉核销的订单
            Predicate<AmLoanAccountInfo> getOverDue = loan -> TransBizConstant.LOAN_STATUS_2.equals(loan.getAccountStatus())
                    && !loan.getChargeoffFlag().equals(TransBizConstant.YES_FLAG);
            List<AmLoanAccountInfo> newLoanAcctList = accountInfos.stream()
                    .filter(getOverDue).collect(Collectors.toList());

            //若验证后的订单列表不为空
            if (CollectionUtils.isEmpty(newLoanAcctList)) {
                continue;
            }

            //查询客戶下处理中的还款流水
            List<String> sumStatusList = Arrays.asList(TransBizConstant.PAYMENT_LOG_SUM_STATUS_O,
                    TransBizConstant.PAYMENT_LOG_SUM_STATUS_T, TransBizConstant.PAYMENT_LOG_SUM_STATUS_D);
            List<TlPaymentLog> tlPaymentLogList =
                    extTlPaymentLogMapper.selectListBySumStatusForBatch(customerInfo.getCustomerId(),
                            prSmsSendingRules.getChannel(), sumStatusList)
                            .stream().filter(x -> productIds.contains(x.getProductId())).collect(Collectors.toList());

            //还款流水不空 与订单匹配
            if (CollectionUtils.isNotEmpty(tlPaymentLogList)) {
                List<String> seqNoList = tlPaymentLogList.stream().map(TlPaymentLog::getSeqNo).collect(Collectors.toList());
                //获取还款流水对应的订单信息
                List<String> loanIdList = extTlPaymentMappingMapper.selectBySeqNoListForBatch(seqNoList);
                //剔除正在还款中的数据
                newLoanAcctList.removeIf(amLoanAccountInfo -> loanIdList.contains(amLoanAccountInfo.getLoanId()));
            }

            //若验证后的订单列表不为空
            if (CollectionUtils.isEmpty(newLoanAcctList)) {
                continue;
            }

            //按照客户计算待还总金额
            BigDecimal totalDebt = BigDecimal.ZERO;
            //遍历订单计算欠款
            for (AmLoanAccountInfo amLoanAccountInfo : newLoanAcctList) {
                //计算欠款
                DebtBean debtBean = debtCalculationService.getBalance(amLoanAccountInfo, busiDate,
                        null, true, true, null);
                //没有欠款 跳过
                if (debtBean.getTotalAmount().compareTo(BigDecimal.ZERO) < 1) {
                    continue;
                }
                totalDebt = totalDebt.add(debtBean.getTotalAmount());
            }
            if (totalDebt.compareTo(BigDecimal.ZERO) <= 0) {
                continue;
            }

            //组装短信实体
            TlSmsLog tlSmsLog = BeanMapping.copy(prSmsSendingRules, TlSmsLog.class);
            try {
                tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
            }
            //查询客户2级信息获取客户手机号
            CmCustomerSecondLevel secondCust = customerService.getSecondByChannelAndCustomerIdAndTensnId(
                    prSmsSendingRules.getChannel(), customerInfo.getCustomerId(), customerInfo.getTenantId(), null);
            tlSmsLog.setCurrentAmount(totalDebt);//待还总金额
            tlSmsLog.setBusinessDate(busiDate);
            tlSmsLog.setMobile(secondCust.getMobile());
            tlSmsLog.setCustomerId(customerInfo.getCustomerId());
            tlSmsLog.setSmsType(TransBizConstant.SMS_TYPE_OVERDUE_REMINDER);
            tlSmsLog.setSeqNo(SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM));
            tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
            tlSmsLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
            tlSmsLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
            // 兴安借逾期天数特殊处理
            tlSmsLog.setSmsContent(delqDays + "");
            saveList.add(tlSmsLog);
        }
        return saveList;
    }

    /**
     * 根据模板id和天数判断是否发送短信
     * @param prSmsSendingRules
     * @param delqDays
     * @return
     */
    private boolean overdueReminderLevel(PrSmsSendingRules prSmsSendingRules, Integer delqDays) {
        boolean sendFlag = false;
        String templateId = prSmsSendingRules.getTemplateId();
        switch (templateId){
            case TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_18:
                // 一级提醒 1-3天
                if (delqDays.compareTo(3) <= 0) {
                    sendFlag = true;
                }
                break;
            case TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_19:
                // 二级提醒 4-30天
                if (delqDays.compareTo(4) >= 0 && delqDays.compareTo(30) <= 0) {
                    sendFlag = true;
                }
                break;
            case TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_20:
                // 三级提醒 31-60天
                if (delqDays.compareTo(31) >= 0 && delqDays.compareTo(60) <= 0) {
                    sendFlag = true;
                }
                break;
            case TransBizConstant.SMS_OVERDUE_TEMPLATE_XAJ_21:
                // 四级提醒 61天以上
                if (delqDays.compareTo(61) >= 0) {
                    sendFlag = true;
                }
                break;
            default:
                sendFlag = false;
        }
        return sendFlag;
    }


    /**
     * 还款提醒短信
     *
     * @param org
     * @param rules
     * @param maxPoolNumber
     */
    private void sendPayReminder(PrOrganizationTable org, PrSmsSendingRules rules, Integer maxPoolNumber) {
        String productId = rules.getProductId();
        //需要查询的日期 当前业务日期 + 还款提醒周期
        Date queryDate = DateUtils.addDay(org.getNextProcessingDate(), rules.getReminderCycle());
        final Date toDay = org.getNextProcessingDate();
        //查询 贷款账户表 am_loan_account_info
        List<AmLoanAccountInfo> accountList = extAmLoanAccountInfoMapper.selectByProductIdAndNextPaymentDateAndAccountStatus(
                productId, queryDate, Arrays.asList(TransBizConstant.ACCOUNT_STATUS_1, TransBizConstant.ACCOUNT_STATUS_2));
        if (CollectionUtils.isEmpty(accountList)) {
            logger.debug("未获取到相关的贷款账户，产品编号：{},日期：{}", productId, queryDate);
            return;
        }
        //贷款账户总条数
        int size = accountList.size();
        int tl = size % maxPoolNumber == 0 ? size / maxPoolNumber : (size
                / maxPoolNumber + 1);
        int maxPoolNum = maxPoolNumber;
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(maxPoolNum);
        List<Future<String>> futures = new ArrayList<>(maxPoolNumber);
        for (int i = 0; i < maxPoolNum; i++) {
            int end = (i + 1) * tl;
            if (i * tl >= size) {
                break;
            }
            List<AmLoanAccountInfo> proList = accountList.subList(i * tl, Math.min(end, size));
            Callable<String> task = () -> {
                String message = "S";
                //根据贷款账户表，短信发送规则 组装短信流水 入库
                List<TlSmsLog> list = SmsServiceImpl.this.generateSmsLogBypayReminder(rules, proList, toDay);
                // 发送MQ消息
                for (TlSmsLog tlSmsLog : list) {
                    logger.info("开始发送MQ消息，短信流水号：{}", tlSmsLog.getSeqNo());
                    String jSonMessage = JsonUtils.toJSon(tlSmsLog);
                    SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
                    logger.info("放款短信处理完成,流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());
                }
                return message;
            };
            futures.add(fixedThreadPool.submit(task));
        }
        //获取处理结果
        for (Future<String> future : futures) {
            try {
                future.get();
            } catch (Exception e) {
                logger.error("还款提醒短信处理异常 : ", e);
            }
        }
        fixedThreadPool.shutdown();
    }

    /**
     * 发送出账提醒短信
     *
     * @param org
     * @param rules
     * @param maxPoolNumber
     */
    private void sendPaymentReminder(PrOrganizationTable org, PrSmsSendingRules rules, Integer maxPoolNumber) {
        if (StringUtils.isBlank(rules.getChannel())) {
            logger.info("发送规则未选择渠道，规则编号 ：" + rules.getRulesId());
            return;
        }

        final Date toDay = org.getNextProcessingDate();

        //根据业务日期得到账单日
        Date queryDate = DateUtils.addDay(org.getNextProcessingDate(), rules.getReminderCycle());

        Integer statementDd = Integer.valueOf(DateUtils.format(queryDate).substring(8, 10));
        //根据渠道，账单日期查询客户二级信息表
        List<CmCustomerSecondLevel> secondLevelList = extCmCustomerSecondLevelMapper.findByChannelAndStatementDdOrPaymentDd(org.getTenantId(), rules.getChannel(), statementDd, null);
        if (CollectionUtils.isEmpty(secondLevelList)) {
            logger.info("未获取到相关的客户信息");
            return;
        }

        //贷款账户总条数
        int size = secondLevelList.size();
        int tl = size % maxPoolNumber == 0 ? size / maxPoolNumber : (size
                / maxPoolNumber + 1);
        int maxPoolNum = maxPoolNumber;
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(maxPoolNum);
        List<Future<String>> futures = new ArrayList<>(maxPoolNumber);
        for (int i = 0; i < maxPoolNum; i++) {
            int end = (i + 1) * tl;
            if (i * tl >= size) {
                break;
            }
            List<CmCustomerSecondLevel> secondList = secondLevelList.subList(i * tl, Math.min(end, size));
            Callable<String> task = () -> {
                String message = "S";
                //根据贷款账户表，短信发送规则 组装短信流水 入库
                List<TlSmsLog> list = SmsServiceImpl.this.generateSmsLogByPaymentReminder(rules, secondList, TransBizConstant.SMS_TYPE_PAYMENT_REMINDER);
                // 发送MQ消息
                for (TlSmsLog tlSmsLog : list) {
                    logger.info("开始发送MQ消息，短信流水号：{}", tlSmsLog.getSeqNo());
                    String jSonMessage = JsonUtils.toJSon(tlSmsLog);
                    SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
                    logger.info("放款短信处理完成,流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());
                }
                return message;
            };
            futures.add(fixedThreadPool.submit(task));
        }
        //获取处理结果
        for (Future<String> future : futures) {
            try {
                future.get();
            } catch (Exception e) {
                logger.error("出账提醒短信处理异常 : ", e);
            }
        }
        fixedThreadPool.shutdown();
    }

    /**
     * 发送账单还款提醒
     *
     * @param org
     * @param rules
     * @param maxPoolNumber
     */
    private void sendBillPayReminder(PrOrganizationTable org, PrSmsSendingRules rules, Integer maxPoolNumber) {
        if (StringUtils.isBlank(rules.getChannel())) {
            logger.debug("发送规则未选择渠道，规则编号 ：" + rules.getRulesId());
            return;
        }

        final Date toDay = org.getNextProcessingDate();

        //根据业务日期得到账单日
        Date queryDate = DateUtils.addDay(org.getNextProcessingDate(), rules.getReminderCycle());

        Integer paymentDd = Integer.valueOf(DateUtils.format(queryDate).substring(8, 10));
        //根据渠道，账单日期查询客户二级信息表
        List<CmCustomerSecondLevel> secondLevelList = extCmCustomerSecondLevelMapper.findByChannelAndStatementDdOrPaymentDd(org.getTenantId(), rules.getChannel(), null, paymentDd);
        if (CollectionUtils.isEmpty(secondLevelList)) {
            logger.debug("未获取到相关的客户信息");
            return;
        }

        //贷款账户总条数
        int size = secondLevelList.size();
        int tl = size % maxPoolNumber == 0 ? size / maxPoolNumber : (size
                / maxPoolNumber + 1);
        int maxPoolNum = maxPoolNumber;
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(maxPoolNum);
        List<Future<String>> futures = new ArrayList<>(maxPoolNumber);
        for (int i = 0; i < maxPoolNum; i++) {
            int end = (i + 1) * tl;
            if (i * tl >= size) {
                break;
            }
            List<CmCustomerSecondLevel> secondList = secondLevelList.subList(i * tl, Math.min(end, size));
            Callable<String> task = () -> {
                String message = "S";
                //根据贷款账户表，短信发送规则 组装短信流水 入库
                List<TlSmsLog> list = SmsServiceImpl.this.generateSmsLogByPaymentReminder(rules, secondList, TransBizConstant.SMS_TYPE_BILL_PAY_REMINDER);
                // 发送MQ消息
                for (TlSmsLog tlSmsLog : list) {
                    logger.info("开始发送MQ消息，短信流水号：{}", tlSmsLog.getSeqNo());
                    String jSonMessage = JsonUtils.toJSon(tlSmsLog);
                    SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
                    logger.info("放款短信处理完成,流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());
                }
                return message;
            };
            futures.add(fixedThreadPool.submit(task));
        }
        //获取处理结果
        for (Future<String> future : futures) {
            try {
                future.get();
            } catch (Exception e) {
                logger.error("出账提醒短信处理异常 : ", e);
            }
        }
        fixedThreadPool.shutdown();
    }


    /**
     * 账单逾期还款提醒
     *
     * @param org
     * @param rules
     * @param maxPoolNumber
     */
    private void sendOverdueReminder(PrOrganizationTable org, PrSmsSendingRules rules, Integer maxPoolNumber) {
        //获取需要发短信的产品
        List<String> prAutoPaymentTables = extPrAutoPaymentTableMapper.selectProIdByAutoPaymentFlag(TransBizConstant.YES_FLAG);
        for (String productIdString : prAutoPaymentTables) {
            List<String> productIds = new ArrayList<>();
            productIds.addAll(Arrays.asList(productIdString.split(",")));

            //当前短信规则不适用于当前产品的产品
            if (!productIds.contains(rules.getProductId())) {
                continue;
            }

            //查询所有客户
            List<CmCustomerFirstLevel> cmCustomerFirstLevels = extCmCustomerFirstLevelMapper.selectAllCust();
            if (CollectionUtils.isEmpty(cmCustomerFirstLevels)) {
                continue;
            }

            //客户总条数
            int size = cmCustomerFirstLevels.size();
            int tl = size % maxPoolNumber == 0 ? size / maxPoolNumber : (size
                    / maxPoolNumber + 1);
            int maxPoolNum = maxPoolNumber;
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(maxPoolNum);
            List<Future<String>> futures = new ArrayList<>(maxPoolNumber);
            for (int i = 0; i < maxPoolNum; i++) {
                int end = (i + 1) * tl;
                if (i * tl >= size) {
                    break;
                }
                List<CmCustomerFirstLevel> proList = cmCustomerFirstLevels.subList(i * tl, Math.min(end, size));
                Callable<String> task = () -> {
                    String message = "S";
                    //根据贷款账户表，短信发送规则 组装短信流水 入库
                    List<TlSmsLog> list = SmsServiceImpl.this.generateSmsLogByOverdueReminder(rules, proList, org.getNextProcessingDate(), productIds);
                    // 发送MQ消息
                    for (TlSmsLog tlSmsLog : list) {
                        logger.info("账单逾期还款提醒短信开始发送MQ消息，流水号：{}", tlSmsLog.getSeqNo());
                        String jSonMessage = JsonUtils.toJSon(tlSmsLog);
                        SendResult sendResult = rocketMQTemplate.syncSend(TransBizConstant.MQ_SMS_TOPIC + grayVersionConfig.getCurrentVersion(), jSonMessage);
                        logger.info("账单逾期还款提醒短信处理完成,流水号:{},结果：{}", tlSmsLog.getSeqNo(), sendResult.toString());
                    }
                    return message;
                };
                futures.add(fixedThreadPool.submit(task));
            }
            //获取处理结果
            for (
                    Future<String> future : futures) {
                try {
                    future.get();
                } catch (Exception e) {
                    logger.error("账单逾期还款提醒短信处理异常 : ", e);
                }
            }
            fixedThreadPool.shutdown();
        }
    }


    private List<TlSmsLog> generateSmsLogByPaymentReminder(PrSmsSendingRules
                                                                   prSmsSendingRules, List<CmCustomerSecondLevel> secondLevels, String smsType) throws TxnException {
        logger.info("根据还款计划组装短信流水");
        List<TlSmsLog> saveList = new ArrayList<>();
        for (CmCustomerSecondLevel secondLevel : secondLevels) {

            LoanBillQueryRes loanBillQueryRes = getCurrAmount(prSmsSendingRules, secondLevel);
            //当期金额 = 当期账单金额 + 逾期金额
            BigDecimal currAmount = loanBillQueryRes.getCurrentAmount().add(loanBillQueryRes.getDelqAmount());

            logger.info("客户ID：{},当期总金额：{}", secondLevel.getCustomerId(), currAmount);
            if (currAmount.compareTo(BigDecimal.ZERO) <= 0) {
                //当期无欠款
                continue;
            }

            TlSmsLog tlSmsLog = BeanMapping.copy(prSmsSendingRules, TlSmsLog.class);
            try {
                tlSmsLog.setId(segmentService.getId(TransBizConstant.TL_SMS_LOG_ID));
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
            }

            tlSmsLog.setCurrentAmount(currAmount);//当期总金额 + 逾期金额
            if (TransBizConstant.YES_FLAG.equals(loanBillQueryRes.getCanStaging())) {
                tlSmsLog.setCanStagingAmount(loanBillQueryRes.getCanStagingAmount());
            } else {
                tlSmsLog.setCanStagingAmount(BigDecimal.ZERO);
            }
            tlSmsLog.setCustomerId(secondLevel.getCustomerId());
            tlSmsLog.setOrganizationId(secondLevel.getOrganizationId());
            tlSmsLog.setProductId(prSmsSendingRules.getProductId());
            tlSmsLog.setMobile(secondLevel.getMobile());
            tlSmsLog.setTemplateId(prSmsSendingRules.getTemplateId());
            tlSmsLog.setSmsType(smsType);
            tlSmsLog.setSeqNo(SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM));
            tlSmsLog.setSendStatus(TransBizConstant.SMS_SEND_STATUS_D);
            tlSmsLog.setBusinessDate(loanBillQueryRes.getPaymentDate());//当期还款日
            tlSmsLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
            tlSmsLog.setSendType(prSmsSendingRules.getSendType());
            tlSmsLog.setChannel(prSmsSendingRules.getChannel());
            tlSmsLog.setWxTemplateId(prSmsSendingRules.getWxTemplateId());
            tlSmsLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
            saveList.add(tlSmsLog);
        }
        return saveList;
    }

    String generateTxnTime(AmLoanMainInfo amLoanMainInfo) {
        String txnTime = DateUtils.format(amLoanMainInfo.getTxnTime(), "dd日HH:mm");
        if (BizTypeProducts.PRODUCT_XYJY.equals(amLoanMainInfo.getProductId())) {
            //信用就医的消费时间仅精确至天
            txnTime = DateUtils.format(amLoanMainInfo.getPostingDate(), DateUtils.DATE_PATTERN_ZH);
        } else {
            /*if (!DateUtils.sameDate(DateUtils.parseDate(amLoanMainInfo.getTxnTime()).getTime(), DateUtils.parseDate(amLoanMainInfo.getCreateTime()).getTime())) {
                // 23.30 切日后，前端显示实际发生的时间
                txnTime = DateUtils.format(DateUtils.addDay(amLoanMainInfo.getTxnTime(), -1), "dd日HH:mm");
            }*/
        }
        return txnTime;
    }

    /**
     * 获取客户的姓氏
     *
     * @param name
     * @return
     */
    private String getFamilyName(String name) {
        String familyName = "";
        //复姓
        List<String> RepeatedFamilyName = Arrays.asList("欧阳", "太史",
                "端木", "上官", "司马", "东方", "独孤", "南宫", "万俟", "闻人", "夏侯",
                "诸葛", "尉迟", "公羊", "赫连", "澹台", "皇甫", "宗政", "濮阳", "公冶",
                "太叔", "申屠", "公孙", "慕容", "仲孙", "钟离", "长孙", "宇文", "司徒",
                "鲜于", "司空", "闾丘", "子车", "亓官", "司寇", "巫马", "公西", "颛孙",
                "壤驷", "公良", "漆雕", "乐正", "宰父", "谷梁", "拓跋", "夹谷", "轩辕",
                "令狐", "段干", "百里", "呼延", "东郭", "南门", "羊舌", "微生", "公户",
                "公玉", "公仪", "梁丘", "公仲", "公上", "公门", "公山", "公坚", "左丘",
                "公伯", "西门", "公祖", "第五", "公乘", "贯丘", "公皙", "南荣", "东里",
                "东宫", "仲长", "子书", "子桑", "即墨", "达奚", "褚师");

        String frontTwoChar = name.substring(0, 2);

        if (RepeatedFamilyName.contains(frontTwoChar)) {
            familyName = frontTwoChar;
        } else {
            familyName = name.substring(0, 1);
        }
        return familyName;
    }

}

